import { ReactComponentExt } from '@helpers/ReactExt'
import { BaseProps } from '@store/store'
import { Col, DatePicker, Form, Input, InputNumber, Select, TimePicker } from 'antd'
import { FormComponentProps } from 'antd/lib/form'
import { UploadFile } from 'antd/lib/upload/interface'
import * as React from 'react'
import { UploadWrapper } from '../uploadWrapper/uploadWrapper'

const { Option } = Select
const { TextArea } = Input
const Item = Form.Item
const { RangePicker } = DatePicker
const formItemLayout = {
  labelCol: { span: 8 },
  wrapperCol: { span: 16 }
}

// tslint:disable-next-line:no-empty-interface
export interface FormFieldWrapperProps<T = {}> extends BaseProps, FormComponentProps {
  formFieldConfig: FieldInter[]
  span: number,
  action?: 'look' | 'edit' | 'create'
  data?: T
}

// tslint:disable-next-line:no-empty-interface
interface FormFieldWrapperState {
}

export class FormFieldWrapper<T extends object> extends ReactComponentExt<
  FormFieldWrapperProps<T>,
  FormFieldWrapperState> {
  public init(): void {
    this.handlePreviewStudentAvatar = this.handlePreviewStudentAvatar.bind(this)
    this.handleUploadAvatarSuccess = this.handleUploadAvatarSuccess.bind(this)
    this.handleUploading = this.handleUploading.bind(this)
  }

  public componentDidMount() {
    // todo
  }

  public render() {
    return (
      this.renderFields()
    )
  }

  private renderSelectComp(values: FieldInter['value']) {
    const { action } = this.props
    const fn = () => {
      return values!.map((v) => {
        return <Option key={v.key} value={v.key} >{v.val}</Option>
      })
    }
    return (
      <Select disabled={action === 'look'}>
        {fn()}
      </Select>
    )
  }

  private renderDateRange() {
    const { action } = this.props
    return (
      <RangePicker
        format='YYYY-MM-DD'
        style={{ width: '100%' }}
        disabled={action === 'look'}
      />
    )
  }

  private renderDate() {
    const { action } = this.props
    return (
      <DatePicker
        format='YYYY-MM-DD HH:mm:ss'
        showToday
        style={{ width: '100%' }}
        placeholder='请选择时间'
        disabled={action === 'look'}
      />
    )
  }

  private handlePreviewStudentAvatar(file: UploadFile) {
    // todo
  }

  private handleUploading(filename: string, fileList: UploadFile[]) {
    const { form } = this.props
    form.setFieldsValue({ [filename]: fileList })
  }

  private handleUploadAvatarSuccess(filename: string, fileList: UploadFile[]) {
    const { form } = this.props
    form.setFieldsValue({ [filename]: fileList })
  }

  private renderUpload(count: number, type: string, fieldname: string) {
    const { action } = this.props
    return (
      <UploadWrapper
        onUploading={this.handleUploading}
        count={count}
        fieldname={fieldname}
        acceptType={type}
        disabled={action === 'look'}
        onPreview={this.handlePreviewStudentAvatar}
        onSuccess={this.handleUploadAvatarSuccess}
      />
    )
  }

  private genInitValue(): FieldInter[] {
    const { formFieldConfig, data } = this.props
    const configs = formFieldConfig
    const d = data || []
    const set = new Set(Object.keys(d))
    for (const f of formFieldConfig) {
      const key = f.field as keyof typeof data
      if (set.has(key)) {
        f.initialize = d[key]
      }
    }
    return configs
  }

  private renderFields() {
    const { form,   span, action } = this.props
    const { getFieldDecorator } = form
    return this.genInitValue().map((fieldItem, index) => {
      const { initialize,   count, acceptType, placeholder, type, label, field, rule, value } = fieldItem

      let el = <Input placeholder={placeholder} disabled={action === 'look'} />
      if (type === 'select') {
        el = this.renderSelectComp(value)
      } else if (type === 'date') {
        el = this.renderDate()
      } else if (type === 'dataRange') {
        el = this.renderDateRange()
      } else if (type === 'textarea') {
        el = (<TextArea placeholder={placeholder} disabled={action === 'look'} />)
      } else if (type === 'upload') {
        el = this.renderUpload(count || 1, acceptType!, field)
      } else if (type === 'number') {
        el = (<InputNumber disabled={action === 'look'} min={1} style={{ width: '100%' }} />)
      } else if (type === 'time') {
        el = <TimePicker style={{ width: '100%' }} placeholder={placeholder}/>
      }
      let options = {
        rules:   rule,
        initialValue: initialize
      }
      if (type === 'upload') {
        options = Object.assign(options, {
          valuePropName: 'fileList',
        })
      }
      return (
        <Col span={span} key={index} >
          <Item label={label} {...formItemLayout}>
            {getFieldDecorator(field, options)(el)}
          </Item>
        </Col>
      )
    })
  }

}
